//
//  AFNetworkManager.m
//  OilUnion
//
//  Created by itte on 2016/11/10.
//  Copyright © 2016年 funmain. All rights reserved.
//

#import "AFNetworkManager.h"
#import <AFNetworking.h>
#import <AFNetworkActivityIndicatorManager.h>
#import "NSString+More.h"
#import "MBProgressHUD.h"
#import "MBProgressHUD+More.h"

@interface AFNetworkManager ()
@property (strong, nonatomic) NSMutableArray *task;   // 执行的任务数组
@property (strong, nonatomic) NSSet *cerSet;          // 证书集合
@end

@implementation AFNetworkManager

+(AFNetworkManager *)sharedInstance
{
    static dispatch_once_t onceTocken;
    __strong static id _sharedObject = nil;
    dispatch_once(&onceTocken, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}


-(NSMutableArray *)task
{
    if (_task) {
        _task = [[NSMutableArray alloc] init];
    }
    return _task;
}

-(void)dealloc
{
    [[AFNetworkReachabilityManager sharedManager] stopMonitoring];
}

-(AFHTTPSessionManager *)getHttpManager
{
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    AFHTTPSessionManager *manager  = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];   // 请求
    manager.responseSerializer = [AFJSONResponseSerializer serializer]; //设置返回数据为json
    manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
    manager.requestSerializer.timeoutInterval= 30;
    
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                                                                              @"text/html",
                                                                              @"text/json",
                                                                              @"text/plain",
                                                                              @"text/javascript",
                                                                              @"text/xml",
                                                                              @"image/*"]];
    return manager;
}

#pragma mark - 开始监听程序在运行中的网络连接变化
-(void)startNetworkMonitor
{
    // 1.获得网络监控的管理者
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    // 2.设置网络状态改变后的处理
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        // 当网络状态改变了, 就会调用这个block
        switch (status)
        {
            case AFNetworkReachabilityStatusUnknown: // 未知网络
                [AFNetworkManager sharedInstance].networkStatus = StatusUnknown;
                break;
            case AFNetworkReachabilityStatusNotReachable: // 没有网络(断网)
                [AFNetworkManager sharedInstance].networkStatus = StatusNotReachable;
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN: // 手机自带网络
                [AFNetworkManager sharedInstance].networkStatus = StatusReachableViaWWAN;
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi: // WIFI
                [AFNetworkManager sharedInstance].networkStatus = StatusReachableViaWiFi;
                break;
        }
    }];
    
    [mgr startMonitoring];
}
/**
 * 检查网络状态
 *@return 返回网络状态
 */
- (NetworkStatus)checkNetStatus {
    
    [self startNetworkMonitor];
    
    if ([AFNetworkManager sharedInstance].networkStatus == StatusReachableViaWiFi) {
        return StatusReachableViaWiFi;
    }
    else if ([AFNetworkManager sharedInstance].networkStatus == StatusNotReachable) {
        return StatusNotReachable;
    }
    else if ([AFNetworkManager sharedInstance].networkStatus == StatusReachableViaWWAN) {
        return StatusReachableViaWWAN;
    }
    else {
        return StatusUnknown;
    }
}

#pragma mark - 网络请求基础
/**
 *生成SessionID
 *@param url 字符串
 *@param params 字典dictionary
 *@return SessionID字符串
 */
-(NSString *)getSessionIDWithUrl:(NSString *)url withParams:(NSDictionary *)params
{
    url = url.trimString;
    if (params) {
        NSArray *keyArray = [params allKeys];
        for (NSString *key in keyArray) {
            url = [NSString stringWithFormat:@"%@&%@",url,key];
        }
    }
    return [url md5FromString];
}

/**
 * 生成证书集合
 *@return 返回证书结合
 */

-(NSSet *)cerSet
{
    if (_cerSet == nil) {
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"https_etoil" ofType:@"cer"];
        NSData *certData = [NSData dataWithContentsOfFile:cerPath];
        _cerSet = [[NSSet alloc] initWithObjects:certData, nil];
    }
    return _cerSet;
}

/**
 *  post 或者 get 请求方法,block回调
 *  @param requestType      网络请求类型
 *  @param requestMethod    网络请求方法
 *  @param url              请求连接，根路径
 *  @param header           请求头
 *  @param params           参数字典
 *  @param loadingImageArr  loading图片数组
 *  @param showView         HUD 展示view
 *  @param success          请求成功返回数据
 *  @param fail             请求失败
 *  @param showHUD          是否显示HUD
 */
-(void)getOrPostWithType:(RequestType)requestType
              WithMethod:(RequestMethod)requestMethod
                 WithUrl:(NSString *)url
              withHeader:(NSString *)header
                  params:(NSDictionary *)params
         loadingImageArr:(NSMutableArray *)loadingImageArr
           toShowHUDView:(UIView *)showView
                 success:(RequestSuccessed)success
                    fail:(RequestFailure)fail
                 showHUD:(BOOL)showHUD
{
    if(url == nil){
        return ;
    }
    NSString *sessionID = [self getSessionIDWithUrl:url withParams:params];
    // 如果请求在请求dictSession中
    if([[AFNetworkManager sharedInstance].task containsObject:sessionID]){
        return ;
    }
    if (showHUD == YES) {
        if (loadingImageArr && loadingImageArr.count > 0) {
            [MBProgressHUD showHUDWithImageArr:loadingImageArr andShowView:showView];
        }
        else{
            [MBProgressHUD showHUDAddedTo:showView animated:YES];
        }
    }
    
    AFHTTPSessionManager *manager = [self getHttpManager];
    [manager.requestSerializer setValue:header forHTTPHeaderField:@"Authorization"];
    // https类型
    if (requestType == HTTPS) {
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
        securityPolicy.allowInvalidCertificates = YES;
        securityPolicy.validatesDomainName = NO;
        // 设置证书
        [securityPolicy setPinnedCertificates:self.cerSet];
        manager.securityPolicy = securityPolicy;
    }
    
    NSURLSessionDataTask *sessionTask = nil;
    // get请求
    if (requestMethod == GET) {
        sessionTask = [manager GET:url parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"--BaseURL：%@",url);
            NSLog(@"--返回结果：%@",responseObject);
            if (showHUD == YES) {
                [MBProgressHUD hideFromShowView:showView];
            }
            [[AFNetworkManager sharedInstance].task removeObject:sessionID];
            if (success) {
                FSCommonModel *commModel = [FSCommonModel mj_objectWithKeyValues:responseObject];
                if ([commModel.status_code.trimString isEqualToString:@"200"]) {
                    success(commModel.data,commModel.message);
                }
                else{
                    if (fail) {
                        fail(commModel.status_code,commModel.message);
                    }
                }
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (showHUD == YES) {
                [MBProgressHUD hideFromShowView:showView];
            }
            [[AFNetworkManager sharedInstance].task removeObject:sessionID];
            if (fail) {
                fail([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription);
            }
        }];
    }
    // post请求
    else{
        sessionTask = [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"--BaseURL：%@",url);
            NSLog(@"--返回结果：%@",responseObject);
            if (showHUD == YES) {
                [MBProgressHUD hideFromShowView:showView];
            }
            [[AFNetworkManager sharedInstance].task removeObject:sessionID];
            if (success) {
                FSCommonModel *commModel = [FSCommonModel mj_objectWithKeyValues:responseObject];
                if ([commModel.status_code.trimString isEqualToString:@"200"]) {
                    success(commModel.data,commModel.message);
                }
                else{
                    if (fail) {
                        fail(commModel.status_code,commModel.message);
                    }
                }
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (showHUD == YES) {
                [MBProgressHUD hideFromShowView:showView];
            }
            [[AFNetworkManager sharedInstance].task removeObject:sessionID];
            if (fail) {
                fail([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription);
            }
        }];
    }
    
    if (sessionTask) {
        [[AFNetworkManager sharedInstance].task addObject:sessionID];
    }
}

/**
 *  post 或者 get 请求方法,block回调
 *  @param requestType      网络请求类型
 *  @param url              请求连接，根路径
 *  @param image            图片
 *  @param params           参数字典
 *  @param success          请求成功返回数据
 *  @param fail             请求失败
 */
-(void)uploadImageWithType:(RequestType)requestType
                   WithUrl:(NSString *)url
                 withImage:(UIImage *)image
                    params:(NSDictionary *)params
                   success:(RequestSuccessed)success
                      fail:(RequestFailure)fail
{
    if(url == nil){
        return ;
    }
    NSString *sessionID = [self getSessionIDWithUrl:url withParams:params];
    // 如果请求在请求dictSession中
    if([[AFNetworkManager sharedInstance].task containsObject:sessionID]){
        return ;
    }
    AFHTTPSessionManager *manager = [self getHttpManager];
    // https类型
    if (requestType == HTTPS) {
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
        securityPolicy.allowInvalidCertificates = YES;
        securityPolicy.validatesDomainName = YES;
        // 设置证书
        [securityPolicy setPinnedCertificates:self.cerSet];
        manager.securityPolicy = securityPolicy;
    }
    
    NSURLSessionDataTask *sessionTask = [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        NSData *imgData = UIImageJPEGRepresentation(image, 0.8);
        [formData appendPartWithFileData:imgData
                                    name:@"file"
                                fileName:@"head.png"
                                mimeType:@"image/jpeg"];
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[AFNetworkManager sharedInstance].task removeObject:sessionID];
        if (success) {
            success(responseObject,@"");
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[AFNetworkManager sharedInstance].task removeObject:sessionID];
        if (fail) {
            fail([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription);
        }
    }];
    if (sessionTask) {
        [[AFNetworkManager sharedInstance].task addObject:sessionID];
    }
}

#pragma mark - 常用的http请求
// get请求
-(void)httpGetWithUrl:(NSString *)url
               params:(NSDictionary *)params
              showHUD:(BOOL)showHUD
        toShowHUDView:(UIView *)showView
              success:(RequestSuccessed)success
                 fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    [dictParams setObject:NSLocalizedString(@"lang", nil) forKey:@"Language"];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    NSString *header = @"";
    if([FSLogin sharedInstance].isLogined){
        FSTokenModel *token = [[FSLogin sharedInstance] getToken];
        header = [NSString stringWithFormat:@"%@ %@",token.token_type,token.access_token];
    }
    [self getOrPostWithType:HTTP WithMethod:GET WithUrl:url withHeader:header params:dictParams loadingImageArr:nil toShowHUDView:showView success:success fail:fail showHUD:showHUD];
}
// post请求
-(void)httpPostWithUrl:(NSString *)url
                params:(NSDictionary *)params
               showHUD:(BOOL)showHUD
         toShowHUDView:(UIView *)showView
               success:(RequestSuccessed)success
                  fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    NSString *header = @"";
    if([FSLogin sharedInstance].isLogined){
        FSTokenModel *token = [[FSLogin sharedInstance] getToken];
        header = [NSString stringWithFormat:@"%@ %@",token.token_type,token.access_token];
    }
    [self getOrPostWithType:HTTP WithMethod:POST WithUrl:url withHeader:header params:dictParams loadingImageArr:nil toShowHUDView:showView success:success fail:fail showHUD:showHUD];
}

// 文件上传
-(void)httpUploadImageWithUrl:(NSString *)url
                    withImage:(UIImage *)image
                       params:(NSDictionary *)params
                      success:(RequestSuccessed)success
                         fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    [self uploadImageWithType:HTTP WithUrl:url withImage:image params:dictParams success:success fail:fail];
}

#pragma mark - 常用的https请求
// get请求
-(void)httpsGetWithUrl:(NSString *)url
                params:(NSDictionary *)params
               showHUD:(BOOL)showHUD
         toShowHUDView:(UIView *)showView
               success:(RequestSuccessed)success
                  fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    NSString *header = @"";
    if([FSLogin sharedInstance].isLogined){
        FSTokenModel *token = [[FSLogin sharedInstance] getToken];
        header = [NSString stringWithFormat:@"%@ %@",token.token_type,token.access_token];
    }
    [self getOrPostWithType:HTTPS WithMethod:GET WithUrl:url withHeader:header params:dictParams loadingImageArr:nil toShowHUDView:showView success:success fail:fail showHUD:showHUD];
}
// post请求
-(void)httpsPostWithUrl:(NSString *)url
                 params:(NSDictionary *)params
                showHUD:(BOOL)showHUD
          toShowHUDView:(UIView *)showView
                success:(RequestSuccessed)success
                   fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    NSString *header = @"";
    if([FSLogin sharedInstance].isLogined){
        FSTokenModel *token = [[FSLogin sharedInstance] getToken];
        header = [NSString stringWithFormat:@"%@ %@",token.token_type,token.access_token];
    }
    [self getOrPostWithType:HTTPS WithMethod:POST WithUrl:url withHeader:header params:dictParams loadingImageArr:nil toShowHUDView:showView success:success fail:fail showHUD:showHUD];
}

// 文件上传
-(void)httpsUploadImageWithUrl:(NSString *)url
                    withImage:(UIImage *)image
                       params:(NSDictionary *)params
                      success:(RequestSuccessed)success
                         fail:(RequestFailure)fail
{
    NSMutableDictionary *dictParams = [NSMutableDictionary dictionaryWithDictionary:params];
    url = [NSString stringWithFormat:@"%@%@",kBaseURL,url];
    [self uploadImageWithType:HTTPS WithUrl:url withImage:image params:dictParams success:success fail:fail];
}

@end
